package com.nineclock.auth.intergration.aop;

import com.nineclock.auth.intergration.entity.IntergrationAuthenticationEntity;
import com.nineclock.auth.intergration.entity.NcOauthTokenDTO;
import com.nineclock.auth.intergration.threadLocal.IntergrationAuthenticationHolder;
import com.nineclock.auth.intergration.threadLocal.UserHolder;
import com.nineclock.common.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class AuthTokenAspect {
    @Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
    public Object postHandleAuthTokenResult(ProceedingJoinPoint joinPoint) {
        log.info("AOP拦截认证请求");
        Object returnObj = null;
        Result<NcOauthTokenDTO> result = null;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

            IntergrationAuthenticationEntity entity = new IntergrationAuthenticationEntity();
            entity.setAuthType(request.getParameter("auth_type"));
            entity.setAuthParameters(request.getParameterMap());
            IntergrationAuthenticationHolder.set(entity);
            returnObj = joinPoint.proceed();
            if (returnObj != null){
                ResponseEntity<OAuth2AccessToken> responseEntity = (ResponseEntity<OAuth2AccessToken>) returnObj;
                if (responseEntity.getStatusCode().is2xxSuccessful()){
                    OAuth2AccessToken oAuth2AccessToken = responseEntity.getBody();
                    NcOauthTokenDTO ncOauthTokenDTO = new NcOauthTokenDTO();
                    ncOauthTokenDTO.setOauth2AccessToken(oAuth2AccessToken);
                    ncOauthTokenDTO.setUser(UserHolder.get());
                    result = Result.success(ncOauthTokenDTO);
                }else {
                    result = Result.errorCodeMessage(responseEntity.getStatusCodeValue(),"认证失败");
                    return ResponseEntity.status(responseEntity.getStatusCode()).body(result);
                }
            }
        } catch (Throwable throwable) {
            log.error("拦截认证请求出错",throwable);
            result = Result.errorCodeMessage(401,throwable.getMessage());

            return ResponseEntity.status(result.getCode()).body(result);
        }finally {
            IntergrationAuthenticationHolder.remove();
            UserHolder.remove();
        }
        return ResponseEntity.ok(result);
    }
}
